package com.jt.service;/**
 * @Author 金帮嘉诚 @Date 2021-08-07 星期六 10:33
 */
/*本类用于测试*/

//import com.jt.mapper.FileMapper;

import com.jt.vo.ImageVO;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;

/**
 * 知识点
 */
@Service
@PropertySource("classpath:/properties/image.properties")
public class FileServiceImpl implements FileService {
    /**
     * 规则说明:
     * 文件磁盘地址:E:/tedu/workspace/JT_IMAGE/yyyy/MM/dd/uuid.jpg 本地访问
     * 网络访问地址:http://image.jt.com/yyyy/MM/dd/uuid.jpg 为了使所有人都能访问 需要网络地址
     */
    //注解@Value 为属性动态赋值
    @Value("${image.localPathDir}")// = "E:/tedu/workspace/JT_IMAGE";//="/usr/local/src/images"
    private String localPathDir;//文件夹目录 本地磁盘前缀
    @Value("${image.localUrlPath}")// = "http://image.jt.com";
    private String localUrlPath;//url目录 网络访问域名

    //1.参数  ~~~已知条件
    //2.干什么 ~~~ 实现文件上传
    //3.返回值: void ImageVO 有效返回

    /**
     * 文件上传案例实现
     * 1.如何保证前端是上传的数据是有效的!!
     * 1.1 校验文件的名称检查是否为图片
     * 1.2 校验是否为恶意程序.
     * 1.3为了提高线索效率 应该分目录存储 1.hash方式 xx/xx/xx/xx/分布不均
     * 2.日期格式 yyyy/MM/dd 目录不断增长
     *
     * @param file
     * @return ImageVO(virtualPath, urlPath, realFileName)
     * virtualPath 虚拟路径 也就是相对于图片文件夹的路径
     * urlPath 网络路径
     * realFileName 文件名
     */

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ImageVO upload(MultipartFile file) throws IOException {
        //1.图片校验 正则
        String fileName = file.getOriginalFilename();
        fileName = fileName.toLowerCase();
        if (!fileName.matches("^.+\\.(jpg|gif|png|jpeg)$")) {
            return null;
        }
        //2.校验是否为恶意程序 判断依据 宽高
        //ImageIO javax提供
        try {////该对象是用来专门操作图片的API
            //BufferedImage java提供
            BufferedImage bufferedImage = ImageIO.read(file.getInputStream());
            int width = bufferedImage.getWidth();
            int height = bufferedImage.getHeight();
            if (width == 0 || height == 0) {
                return null;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        //3.分目录存储文件 /yyyy/MM/dd
        //3.1准备文件根目录
        String dateDir =
                new SimpleDateFormat("/yyyy/MM/dd/").format(new Date());
        //文件所在文件夹的路径
        String dirPath = localPathDir + dateDir;
        //创建该文件夹的对象
        File dirFile = new File(dirPath);
        //判断是否需要创建
        if (!dirFile.exists()) {
            dirFile.mkdirs();
        }
        //4.防止重名 uuid.后缀
        String uuid = UUID.randomUUID().toString().replace("-", "");
        //截取文件类型
        String fileType = fileName.substring(fileName.lastIndexOf("."));
        //拼接新文件名
        String realFileName = uuid + fileType;

        //5.文件上传
        //5.1准备文件的全路径 文件目录/文件名称
        String realFilePath = dirPath + realFileName;
        //5.2实现文件上传
        file.transferTo(new File(realFilePath));
        //准备返回的ImageVO的参数
        String virtualPath = dateDir + realFileName;//virtualPath 虚拟路径 也就是相对于图片文件夹的路径
        String urlPath = localUrlPath + virtualPath;//urlPath 网络路径
        return new ImageVO(virtualPath, urlPath, realFileName);

//************************************照抄老师的实现*******************************************************

//        System.out.println("进入upload............");
        //注意这是SpringMVC提供的API 注意file的类型
        //1.1校验是否为图片类型
//        String fileName = file.getOriginalFilename();
//        assert fileName != null;
//        fileName = fileName.toLowerCase();
//        if (!fileName.matches("^.+\\.(jpg|png|gif|jpeg)$")) {
//            return null;
//        }
//
//        //1.2校验图片类型是否为木马
//        try {
//            BufferedImage bufferedImage = ImageIO.read(file.getInputStream());
//            int width = bufferedImage.getWidth();
//            int height = bufferedImage.getHeight();
//            if (width == 0 || height == 0) {
//                return null;
//            }
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//
//        //2.目录结构
//        //2.1分目录存储 可以以时间维度进行分割yyyy/mm/dd
//        String datePath =//注意/是用于目录分割 //注意此处MM必须大写 不然就是表示分钟
//                new SimpleDateFormat("/yyyy/MM/dd/").format(new Date());
//        //2.2目录拼接
//        String localDir = localPathDir + datePath;
//        //2.3创建目录
//        File dirFile = new File(localDir);
//        if (!dirFile.exists()) {
//            dirFile.mkdirs();
//        }
//
//        //3 文件名称重复 使用uuid防止文件重名 uuid.jpg
//        String uuid = UUID.randomUUID().toString().replace("-", "");
//        //fileName = abc.jpg
//        String fileType = fileName.substring(fileName.lastIndexOf("."));
//        String realFileName = uuid + fileType;
//        // localDir/uuid.jpg
//        String filePathAll = localDir + realFileName;
//        //实现文件上传
//        File realFile = new File(filePathAll);
//        file.transferTo(realFile);
//
//        //封装imageVO对象 //日期/uuid.jpg
//        String virtualPath = datePath + realFileName;
//        //封装虚拟url地址 localUrlPath virtualPath
//        String urlPath = localUrlPath + virtualPath;
//        return new ImageVO(virtualPath, urlPath, realFileName);
//        return null;
    }

    /**
     * 需求是根据virtualPath找到全路径 全路径存在item表 然后删除该路径
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer deleteFile(String virtualPath) {
        //注意new file没有创建文件 只是创建了对象+
        //virtualPath是相对路径
        //localPathDir是存储图片的文件夹的路径
        File file = new File(localPathDir + virtualPath);
//        System.out.println("file.getPath() = " + file.getPath());
        if (file.exists() && file.delete()) {
            return 1;
        }
        return 0;
    }
}
